// json 数据
let arr = [
    {category: 'fruit', name: 'banana', color: 'yellow', count: 2},
    {category: 'person', name: 'kitty', color: 'yellow', count: 2},
    {category: 'animal', name: 'dog', color: 'black', count: 1},
    {category: 'fruit', name: 'pear', color: 'yellow', count: 2},
    {category: 'animal', name: 'pig', color: 'white', count: 6},
    {category: 'fruit', name: 'apple', color: 'red', count: 12},
    {category: 'person', name: 'Tom', color: 'black', count: 2}
];

// 解法一
// =================================================================

let store = [];

class Category {
    constructor({category}) {
        Object.assign(this, {category, children: []});
    }
}

class Info {
    constructor({name, color, count}) {
        Object.assign(this, {name, color, count});
    }
}

arr.forEach(item => {
    let inStore = store.findIndex(n => n.category === item.category);

    if (inStore === -1) {
        let t = new Category(item);

        t.children.push(new Info(item));
        store.push(t);
    } else {
        store[inStore].children.push(new Info(item));
    }
});

// 解法二
// ==================================================================

class Category {
    constructor({category}) {
        Object.assign(this, {category, children: []});
    }
}

class Info {
    constructor({name, color, count}) {
        Object.assign(this, {name, color, count});
    }
}

arr.reduce((accu, curVal, curInx, array) => {
    let inStore = accu.findIndex(n => n.category === curVal.category);

    if (inStore === -1) {
        let t = new Category(curVal);

        t.children.push(new Info(curVal));
        accu.push(t)
    } else {
        accu[inStore].children.push(new Info(curVal));
    }
    return accu
}, []);